React Lazy Loading: ์ตœ์ ํ™”๋œ ์„ฑ๋Šฅ์„ ์œ„ํ•œ ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ ๋ถ„ํ•  | MLOG | MLOG ); } export default ImageGallery;

๊ทธ๋ฆฌ๊ณ  Image.js ์ปดํฌ๋„ŒํŠธ:


import React from 'react';

const Image = ({ src, alt }) => {
  return {alt};
};

export default Image;

์ด ์˜ˆ์—์„œ ๊ฐ ์ด๋ฏธ์ง€๋Š” <Suspense> ์ปดํฌ๋„ŒํŠธ๋กœ ๋ž˜ํ•‘๋˜๋ฏ€๋กœ ๊ฐ ์ด๋ฏธ์ง€๊ฐ€ ๋กœ๋“œ๋˜๋Š” ๋™์•ˆ ๋กœ๋”ฉ ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ด๋ฏธ์ง€๊ฐ€ ๋‹ค์šด๋กœ๋“œ๋˜๋Š” ๋™์•ˆ ์ „์ฒด ํŽ˜์ด์ง€๊ฐ€ ์ฐจ๋‹จ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณ ๊ธ‰ ๊ธฐ์ˆ  ๋ฐ ๊ณ ๋ ค ์‚ฌํ•ญ

1. ์˜ค๋ฅ˜ ๊ฒฝ๊ณ„

Lazy loading์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋กœ๋”ฉ ํ”„๋กœ์„ธ์Šค ์ค‘์— ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ž ์žฌ์ ์ธ ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ๊ฒฝ๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ์˜ค๋ฅ˜๋ฅผ ํฌ์ฐฉํ•˜๊ณ  ํด๋ฐฑ UI๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์˜ค๋ฅ˜ ๊ฒฝ๊ณ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


import React, { Component } from 'react';

class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    console.error(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return 

Something went wrong.

; } return this.props.children; } } export default ErrorBoundary;

๊ทธ๋Ÿฐ ๋‹ค์Œ <Suspense> ์ปดํฌ๋„ŒํŠธ๋ฅผ <ErrorBoundary>๋กœ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค.



  Loading...}>
    
  


MyComponent๋ฅผ ๋กœ๋“œํ•˜๋Š” ๋™์•ˆ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด <ErrorBoundary>๊ฐ€ ์ด๋ฅผ ํฌ์ฐฉํ•˜๊ณ  ํด๋ฐฑ UI๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

2. ์„œ๋ฒ„์ธก ๋ Œ๋”๋ง(SSR) ๋ฐ Lazy Loading

Lazy loading์€ ์„œ๋ฒ„์ธก ๋ Œ๋”๋ง(SSR)๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ดˆ๊ธฐ ๋กœ๋“œ ์‹œ๊ฐ„์„ ๊ฐœ์„ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ๊ตฌ์„ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๊ฐ€ ๋™์  ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ณ  lazy-loaded ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์ธก์—์„œ ์ ์ ˆํ•˜๊ฒŒ ํ•˜์ด๋“œ๋ ˆ์ด์…˜๋˜๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Next.js ๋ฐ Gatsby.js์™€ ๊ฐ™์€ ๋„๊ตฌ๋Š” SSR ํ™˜๊ฒฝ์—์„œ lazy loading ๋ฐ ์ฝ”๋“œ ๋ถ„ํ• ์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•˜๋ฏ€๋กœ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ›จ์”ฌ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค.

3. Lazy-Loaded ์ปดํฌ๋„ŒํŠธ ๋ฏธ๋ฆฌ ๋กœ๋“œ

๊ฒฝ์šฐ์— ๋”ฐ๋ผ ์‹ค์ œ๋กœ ํ•„์š”ํ•˜๊ธฐ ์ „์— lazy-loaded ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ณง ๋ Œ๋”๋ง๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ(์˜ˆ: ํด๋“œ ์•„๋ž˜์— ์žˆ์ง€๋งŒ ์Šคํฌ๋กค๋˜์–ด ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ)์— ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. import() ํ•จ์ˆ˜๋ฅผ ์ˆ˜๋™์œผ๋กœ ํ˜ธ์ถœํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


import('./MyComponent'); // MyComponent ๋ฏธ๋ฆฌ ๋กœ๋“œ

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ปดํฌ๋„ŒํŠธ ๋กœ๋”ฉ์ด ์‹œ์ž‘๋˜๋ฏ€๋กœ ์‹ค์ œ๋กœ ๋ Œ๋”๋ง๋  ๋•Œ ๋” ๋นจ๋ฆฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4. Webpack Magic Comments๋ฅผ ์‚ฌ์šฉํ•œ ๋™์  ๊ฐ€์ ธ์˜ค๊ธฐ

Webpack์˜ "magic comments"๋Š” ์ƒ์„ฑ๋œ ์ฝ”๋“œ ์ฒญํฌ์˜ ์ด๋ฆ„์„ ์‚ฌ์šฉ์ž ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฒˆ๋“ค ๊ตฌ์กฐ๋ฅผ ๋””๋ฒ„๊น…ํ•˜๊ณ  ๋ถ„์„ํ•˜๋Š” ๋ฐ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.


const MyComponent = React.lazy(() => import(/* webpackChunkName: "my-component" */ './MyComponent'));

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ผ๋ฐ˜์ ์ธ ์ด๋ฆ„ ๋Œ€์‹  "my-component.js"(๋˜๋Š” ์œ ์‚ฌํ•œ)๋ผ๋Š” ์ฝ”๋“œ ์ฒญํฌ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

5. ์ผ๋ฐ˜์ ์ธ ํ•จ์ • ํ”ผํ•˜๊ธฐ

์‹ค์ œ ์‚ฌ๋ก€ ๋ฐ ์‚ฌ์šฉ ์‚ฌ๋ก€

Lazy loading์€ React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๊ด‘๋ฒ”์œ„ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋ช‡ ๊ฐ€์ง€ ์˜ˆ์ž…๋‹ˆ๋‹ค.

์˜ˆ: ๊ตญ์ œ ์ „์ž ์ƒ๊ฑฐ๋ž˜ ์›น์‚ฌ์ดํŠธ

์ „ ์„ธ๊ณ„์— ์ œํ’ˆ์„ ํŒ๋งคํ•˜๋Š” ์ „์ž ์ƒ๊ฑฐ๋ž˜ ์›น์‚ฌ์ดํŠธ๋ฅผ ์ƒ์ƒํ•ด ๋ณด์‹ญ์‹œ์˜ค. ๊ตญ๊ฐ€๋งˆ๋‹ค ํ†ตํ™”, ์–ธ์–ด ๋ฐ ์ œํ’ˆ ์นดํƒˆ๋กœ๊ทธ๊ฐ€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ตญ๊ฐ€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•˜๋Š” ๋Œ€์‹  lazy loading์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์ดํŠธ๋ฅผ ๋ฐฉ๋ฌธํ•  ๋•Œ๋งŒ ์‚ฌ์šฉ์ž ์œ„์น˜์™€ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


const CurrencyFormatter = React.lazy(() => import(`./CurrencyFormatter/${userCountry}`))
const ProductCatalog = React.lazy(() => import(`./ProductCatalog/${userCountry}`))

function ECommerceSite() {
  const userCountry = getUserCountry(); // ์‚ฌ์šฉ์ž์˜ ๊ตญ๊ฐ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ํ•จ์ˆ˜

  return (
    Loading content for your region...}>
      
      
    
  );
}

๊ฒฐ๋ก 

Lazy loading ๋ฐ ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ ๋ถ„ํ• ์€ React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•„์š”ํ•  ๋•Œ๋งŒ ๋กœ๋“œํ•˜๋ฉด ์ดˆ๊ธฐ ๋กœ๋“œ ์‹œ๊ฐ„์„ ํฌ๊ฒŒ ์ค„์ด๊ณ  ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ฐœ์„ ํ•˜๋ฉฐ SEO๋ฅผ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React์˜ ๊ธฐ๋ณธ ์ œ๊ณต React.lazy() ๋ฐ <Suspense> ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœ์ ํŠธ์—์„œ lazy loading์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ „ ์„ธ๊ณ„ ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•œ ๋” ๋น ๋ฅด๊ณ  ์‘๋‹ต์„ฑ์ด ๋›ฐ์–ด๋‚˜๊ณ  ๋งค๋ ฅ์ ์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜์‹ญ์‹œ์˜ค.

lazy loading์„ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” ํ•ญ์ƒ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค. ์œ ์šฉํ•œ ํด๋ฐฑ UI๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์ž ์žฌ์ ์ธ ์˜ค๋ฅ˜๋ฅผ ์ •์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ฑ๋Šฅ์„ ์‹ ์ค‘ํ•˜๊ฒŒ ๋ถ„์„ํ•˜์—ฌ ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ๋‹ค์–‘ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‹คํ—˜ํ•˜๊ณ  ํŠน์ • ์š”๊ตฌ ์‚ฌํ•ญ์— ๊ฐ€์žฅ ์ ํ•ฉํ•œ ์†”๋ฃจ์…˜์„ ์ฐพ๋Š” ๊ฒƒ์„ ๋‘๋ ค์›Œํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.